#include "stdafx.h"

#include "DynamicRHI.h"
#include "BoundShaderStateCache.h"

using namespace RenderSystem;

typedef std::map<FBoundShaderStateKey,FCachedBoundShaderStateLink*> FBoundShaderStateCache;
typedef FBoundShaderStateCache::iterator FBoundShaderStateCacheIterator;

/** Lazily initialized bound shader state cache singleton. */
static FBoundShaderStateCache& GetBoundShaderStateCache()
{
	static FBoundShaderStateCache BoundShaderStateCache;
	return BoundShaderStateCache;
}

FCachedBoundShaderStateLink::FCachedBoundShaderStateLink(
	FVertexDeclarationRHIParamRef VertexDeclaration,
	DWORD* StreamStrides,
	FVertexShaderRHIParamRef VertexShader,
	FPixelShaderRHIParamRef PixelShader,
	FBoundShaderStateRHIParamRef InBoundShaderState
	):
	BoundShaderState(InBoundShaderState),
	Key(VertexDeclaration,StreamStrides,VertexShader,PixelShader)
{
	// Add this bound shader state to the cache.
	GetBoundShaderStateCache().insert( FBoundShaderStateCache::value_type(Key,this) );
}

FCachedBoundShaderStateLink::~FCachedBoundShaderStateLink()
{
	GetBoundShaderStateCache().erase(Key);
}

FCachedBoundShaderStateLink* GetCachedBoundShaderState(
	FVertexDeclarationRHIParamRef VertexDeclaration,
	DWORD* StreamStrides,
	FVertexShaderRHIParamRef VertexShader,
	FPixelShaderRHIParamRef PixelShader
	)
{
	// Find the existing bound shader state in the cache.
	FBoundShaderStateCacheIterator ret = GetBoundShaderStateCache().find(
		FBoundShaderStateKey(VertexDeclaration,StreamStrides,VertexShader,PixelShader)
		);

	if( ret == GetBoundShaderStateCache().end() )
		return NULL;

	return ret->second;
}
